package com.sls.game.supply.deal;

import java.net.URLEncoder;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.google.gson.Gson;
import com.sls.core.common.CommonUtil;
import com.sls.core.http.HttpClient;
import com.sls.core.socket.Head;
import com.sls.core.socket.ServerDisponseException;
import com.sls.core.util.PropertiesUtil;
import com.sls.core.util.RSAUtils;
import com.sls.core.util.SHA1Util;
import com.sls.game.common.DeductionRefund;
import com.sls.game.constant.ExceptionCodeDes;
import com.sls.game.dao.BNSalesDAO;
import com.sls.game.dao.DownstreamUserDAO;
import com.sls.game.dao.GoodsOrderDAO;
import com.sls.game.dao.GoodsSupplyManageDAO;
import com.sls.game.pojo.DeductionRefundInfo;
import com.sls.game.pojo.GoodsOrderInfo;
import com.sls.game.pojo.SLSHttpInterfaceInfo;
import com.sls.game.pojo.bnsales.BnSales;
import com.sls.game.pojo.bnsales.BnSalesRespInfo;

public class BNSalsesTradeDeal {

	private static Logger log = Logger.getLogger(BNSalsesTradeDeal.class);
	private static String filename = "bnsales.properties";

	/**
	 * 交易处理
	 * 
	 * @param info
	 * @param originalGoodsId
	 * @param orderId
	 * @param orderTime
	 * @param paymentOrderNo
	 * @param head
	 * @param goodsOrderDAO
	 * @param goodsSupplyManageDAO
	 * @param snnsDAO
	 * @param downstreamUserDAO
	 * @return
	 */
	public static String dealTradeResultOfBNsales(SLSHttpInterfaceInfo info,
			String originalGoodsId, String orderId, String orderTime,
			String paymentOrderNo, Head head, GoodsOrderDAO goodsOrderDAO,
			GoodsSupplyManageDAO goodsSupplyManageDAO, BNSalesDAO bnsalesDAO,
			DownstreamUserDAO downstreamUserDAO) {

		BnSalesRespInfo resInfo = trade(info, originalGoodsId, orderId,
				orderTime, head, goodsOrderDAO, goodsSupplyManageDAO,
				bnsalesDAO);
		// 返回给上层对象
		SLSHttpInterfaceInfo sLSHttpInterfaceInfo = new SLSHttpInterfaceInfo();

		String result = resInfo.getStatus();
		if ("OK".equals(result)) { // 处理中
			sLSHttpInterfaceInfo.setResMsg("SUCCESS");
			sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
			sLSHttpInterfaceInfo.setStatus("ORDER_SUCCESS");
			sLSHttpInterfaceInfo.setSupOrderNo(orderId);
		} else if ("ERR".equals(result) || "DUP".equals(result)) {
			sLSHttpInterfaceInfo.setResMsg("SUCCESS");
			sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
			sLSHttpInterfaceInfo.setStatus("ORDER_DUBIOUS");
			sLSHttpInterfaceInfo.setSupOrderNo(orderId);
		} else { // 失败
			sLSHttpInterfaceInfo.setResMsg("FAILED");
			sLSHttpInterfaceInfo.setFailedCode("208");
			sLSHttpInterfaceInfo.setFailedReason("充值失败");
			sLSHttpInterfaceInfo.setPtOrderNo(info.getPtOrderNo());
			sLSHttpInterfaceInfo.setStatus("ORDER_FAILED");
			sLSHttpInterfaceInfo.setSupOrderNo(orderId);

			GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
			DeductionRefundInfo dedInfo = null;
			String paymentStatus = "";
			// 退款
			dedInfo = DeductionRefund.invokeDeductRefund(info, orderId, "1",
					orderTime, paymentOrderNo, head, goodsOrderDAO);
			if (dedInfo != null) {
				paymentStatus = dedInfo.getPaymentStatus();
			}
			if ("1".equals(paymentStatus)) { // 成功
				goodsOrderInfo.setIsPay("3"); // 退款成功
				// 退款成功，通知下游用户
				DeductionRefund.noticeUserRefundMsg(orderId, dedInfo,
						goodsOrderDAO, downstreamUserDAO, null);

			} else if ("2".equals(paymentStatus)) {
				goodsOrderInfo.setIsPay("2"); // 退款失败
			}
			try {
				// 更新订单
				updateGoodsOrder(orderId, head, goodsOrderInfo, goodsOrderDAO);
			} catch (Exception e) {
				log.error("请求ID：" + head.getRequestId() + "根据退款状态更新订单异常！", e);
				throw new ServerDisponseException(
						ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
						ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
			}
		}
		sLSHttpInterfaceInfo.setGameAccount(info.getGameAccount());
		sLSHttpInterfaceInfo.setUnitPrice(info.getUnitPrice());
		sLSHttpInterfaceInfo.setBuyNum(info.getBuyNum());
		String totalPrice = info.getTotalPrice();
		sLSHttpInterfaceInfo.setTotalPrice(totalPrice);
		Gson gson = CommonUtil.gson();
		String resultBody = gson.toJson(sLSHttpInterfaceInfo);
		return resultBody;
	}

	/**
	 * 交易请求
	 * 
	 * @param info
	 * @param originalGoodsId
	 * @param orderId
	 * @param orderTime
	 * @param head
	 * @param goodsOrderDAO
	 * @param goodsSupplyManageDAO
	 * @param bnsalesDAO
	 * @return
	 */
	private static BnSalesRespInfo trade(SLSHttpInterfaceInfo info,
			String originalGoodsId, String orderId, String orderTime,
			Head head, GoodsOrderDAO goodsOrderDAO,
			GoodsSupplyManageDAO goodsSupplyManageDAO, BNSalesDAO bnsalesDAO) {
		BnSalesRespInfo resInfo = null;
		String url = assembleParameterOfTrade(info, originalGoodsId, orderId,
				orderTime, bnsalesDAO);
		// 发送http请求
		resInfo = sendHttpRequestOfDirectTrade(url, head);
		// 上游订单结果
		String orderResult = "";
		String status = "2";
		if (resInfo != null) {
			// 订单结果
			orderResult = resInfo.getStatus();
			if ("OK".equals(orderResult)) { // 下单成功
				status = "1";
			} else if ("DUP".equals(orderResult)) {
				status = "3"; // 存疑
			} else if ("ERR".equals(orderResult)) {
				status = "3"; // 存疑
			} else {
				status = "0"; // 失败
			}
		}
		GoodsOrderInfo goodsOrderInfo = new GoodsOrderInfo();
		goodsOrderInfo.setStatus(status);
		goodsOrderInfo.setResult(orderResult);
		try {
			// 根据交易返回的结果更新订单表
			updateGoodsOrder(orderId, head, goodsOrderInfo, goodsOrderDAO);
		} catch (Exception e) {
			log.error("请求ID：" + head.getRequestId() + "根据bnesales返回的结果更新订单异常！", e);
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}
		return resInfo;
	}

	/**
	 * 更新订单
	 * 
	 * @param orderId
	 * @param head
	 * @param info
	 * @param goodsOrderDAO
	 */
	private static void updateGoodsOrder(String orderId, Head head,
			GoodsOrderInfo info, GoodsOrderDAO goodsOrderDAO) {
		info.setOrderId(orderId);
		info.setSynOrAsy("0"); // 同步通知标识
		// 数据更新
		try {
			goodsOrderDAO.update(info);
		} catch (Exception e) {
			log.error(
					"updateGoodsOrder处理[" + head.getRequestId() + "]的请求出现异常！",
					e);
			throw new ServerDisponseException(
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getCode(),
					ExceptionCodeDes.ACCESS_DATABASE_ERROR.getDescription());
		}
	}

	/**
	 * 向上游发送交易请求
	 * 
	 * @param address
	 * @param paraStr
	 * @param head
	 * @return
	 */
	private static BnSalesRespInfo sendHttpRequestOfDirectTrade(String url,
			Head head) {
		BnSalesRespInfo resInfo = null;
		HttpClient httpClient = new HttpClient();
		Gson gson = CommonUtil.gson();
		// String esalesPublicKey = PropertiesUtil
		// .getSnnsValue("esalse.public.key");
		try {
			// 供应商返回消息编码方式
			String supplyEncode = "GB2312";
			log.info("请求ID：" + head.getRequestId() + "，发送到bnesales的直充请求url参数为："
					+ url);
			url = URLEncoder.encode(url, supplyEncode);
			String xmlStr = httpClient.doGet(url, supplyEncode);
			if (StringUtils.isNotEmpty(xmlStr)) {
				log.info("请求ID：" + head.getRequestId() + "，bnesales直充返回的结果参数为："
						+ xmlStr);
				// 对返回的xml格式字符串数据进行解析
				resInfo = gson.fromJson(xmlStr, BnSalesRespInfo.class);
			}
		} catch (Exception e) {
			log.error("请求ID：" + head.getRequestId() + "bnesales直充交易请求异常！", e);
			throw new ServerDisponseException(
					ExceptionCodeDes.HTTP_URL_FAILED.getCode(),
					ExceptionCodeDes.HTTP_URL_FAILED.getDescription());
		}
		return resInfo;
	}

	/**
	 * 拼装请求地址
	 * 
	 * @param info
	 * @param originalGoodsId
	 * @param orderId
	 * @param orderTime
	 * @param bnsalesDAO
	 * @param jpayGoodsDAO
	 * @return
	 */
	private static String assembleParameterOfTrade(SLSHttpInterfaceInfo info,
			String originalGoodsId, String orderId, String orderTime,
			BNSalesDAO bnsalesDAO) {
		String url = "";
		String address = PropertiesUtil.getValue(
				"esalse.interface.recharge.address", filename);
		String site_id = PropertiesUtil.getValue("esalse.interface.site.id",
				filename);
		String user_id = PropertiesUtil.getValue("esalse.interface.user.id",
				filename);
		String privateKey = PropertiesUtil
				.getValue("sls.private.key", filename);
		orderTime = removeSymbolAndSpace(orderTime);
		String bn_ac = info.getGameAccount();
		String pts = info.getBuyNum();

		String reason = "";
		BnSales bns = bnsalesDAO.queryByGoodsId(originalGoodsId);
		if (bns != null) {
			reason = bns.getReason();
		}
		// site_id+user_id+order_id+order_time+urs+reason+pts
		String data = site_id + user_id + orderId + orderTime + bn_ac;
		if (StringUtils.isNotEmpty(info.getGame())) {
			data += info.getGame();
		}
		if (StringUtils.isNotEmpty(info.getGame_ac())) {
			data += info.getGame_ac();
		}
		data = data + reason + pts;

		String sign = "";
		data = SHA1Util.encrypt(data);
		try {
			sign = RSAUtils.encryptByPrivateKey(data, privateKey);
		} catch (Exception e) {
			log.error("RSA加密出现异常", e);
		}
		StringBuilder sb = new StringBuilder();
		sb.append(address);
		sb.append("?");
		sb.append("site_id=");
		sb.append(site_id);
		sb.append("&");
		sb.append("user_id=");
		sb.append(user_id);
		sb.append("&");
		sb.append("order_id=");
		sb.append(orderId);
		sb.append("&");
		sb.append("order_time=");
		sb.append(orderTime);
		sb.append("&");
		sb.append("bn_ac=");
		sb.append(bn_ac);
		if (StringUtils.isNotEmpty(info.getGame())) {
			sb.append("&");
			sb.append("game=");
			sb.append(info.getGame());
		}
		if (StringUtils.isNotEmpty(info.getGame_ac())) {
			sb.append("&");
			sb.append("game_ac=");
			sb.append(info.getGame_ac());
		}
		sb.append("&");
		sb.append("reason=");
		sb.append(reason);
		sb.append("&");
		sb.append("sign=");
		sb.append(sign);
		url = sb.toString();
		return url;

	}

	private static String removeSymbolAndSpace(String src) {
		if (StringUtils.isNotEmpty(src)) {
			String target = src.replace("-", "");
			target = target.replace(":", "");
			target = target.replace(" ", "");
			return target;
		}
		return null;
	}

}
